const Client = require('./base-client')
const { QBittorrent } = require('@ctrl/qbittorrent')
const logger = require('../console-logger')
const { sleep } = require('../common')

// qbittorrent client
module.exports = class QBitTorrentClient extends Client{
    constructor(config) {
        super(config)
        this.clientType = 'qbittorrent'
        this.instance = new QBittorrent({
            baseUrl: config.address,
            username: config.loginname,
            password: config.loginpwd,
        })
    }

    
    async getSetting() {
        let res = {}
        const preferences = await this.instance.getPreferences()
        if (preferences) res['downloadDir'] = preferences['save_path']
        const version = await this.instance.getAppVersion()
        if (version) res['version'] = version
        logger.debug('getSetting res: ', preferences, version)
        return res
    }

    async addTorrent(torrentFile, options) {
        // const timestamp = new Date().getTime() + ''
        const addOptions = {
            savepath: options.downloadDir,
            paused: !options.startNow + '',
            // category: timestamp
        }
        
        logger.debug('addTorrent req: ', torrentFile, addOptions)
        const added = await this.instance.addTorrent(torrentFile, addOptions)
        logger.debug('addTorrent res: ', added)
        // let torrent = {}
        // if (added === true) {
        //     logger.debug('getTorrent category: ', timestamp)
        //     await sleep(3000)
        //     const res = await this.instance.listTorrents(null,null,timestamp)
        //     logger.debug('getTorrent res: ', res)
        //     if (res && res.length > 0) torrent = res[0]
        //     if (torrent.hash) {
        //         await this.instance.resetTorrentCategory(torrent.hash)
        //         // 
        //         torrent = this.warpTorrent(torrent)
        //     }
        // }
        // logger.debug('remove category: ', timestamp)
        // await this.instance.removeCategory(timestamp)
        // return torrent
        if (added) return true
    } 
    
    async addMagnet(torrentMagnet, options) {
        // const timestamp = new Date().getTime() + ''
        const addOptions = {
            savepath: options.downloadDir,
            paused: !options.startNow + '',
            // category: timestamp
        }
        logger.debug('addMagnet req: ', torrentMagnet, addOptions)
        const added = await this.instance.addMagnet(torrentMagnet, addOptions)
        logger.debug('addMagnet res: ', added)
        // let torrent = {}
        // if (added === true) {
        //     logger.debug('getTorrent category: ', timestamp)
        //     await sleep(3000)
        //     const res = await this.instance.listTorrents(null,null,timestamp)
        //     logger.debug('getTorrent res: ', res)
        //     if (res && res.length > 0) torrent = res[0]
        //     if (torrent.hash) {
        //         await this.instance.resetTorrentCategory(torrent.hash)
        //         // 
        //         torrent = this.warpTorrent(torrent)
        //     }
        // }
        // logger.debug('remove category: ', timestamp)
        // await this.instance.removeCategory(timestamp)
        // return torrent
        if (added) return true
    }
    async removeTorrent(ids, removeData) {
        logger.debug('removeTorrent req: ', ids, removeData)
        const res = await this.instance.removeTorrent(ids, removeData)
        logger.debug('removeTorrent res: ', res)
        return res
    }
    async startTorrent(ids) {
        logger.debug('startTorrent req: ', ids)
        const res = await this.instance.resumeTorrent(ids)
        logger.debug('startTorrent res: ', res)
        return res
    }
    async stopTorrent(ids) {
        logger.debug('stopTorrent req: ', ids)
        const res = await this.instance.pauseTorrent(ids)
        logger.debug('stopTorrent res: ', res)
        return res
    }
    async verifyTorrent(ids) {
        logger.debug('verifyTorrent req: ', ids)
        const res = await this.instance.recheckTorrent(ids)
        logger.debug('verifyTorrent res: ', res)
        return res
    }
    async setTorrentLocation(ids, location) {
        logger.debug('setTorrentLocation req: ', ids)
        const res = await this.instance.setTorrentLocation(ids, location)
        logger.debug('setTorrentLocation res: ', res)
        return res
    }
    async listTorrents() {
        const torrents = await this.instance.listTorrents()
        return torrents.map(torrent => this.warpTorrent(torrent))
    }

    async getTorrent(id) {
        logger.debug('getTorrent id: ', id)
        const res = await this.instance.listTorrents(id)
        const torrent = res && res.length > 0 ? res[0] : {}
        if (torrent.hash) {
            torrent.files = await this.instance.torrentFiles(torrent.hash)
        }
        logger.debug('getTorrent res: ', torrent)
        return this.warpTorrent(torrent)
    }
    
    warpTorrent(torrent) {
        // 统一返回种子格式
        let warped = {}
        if (torrent) {
            warped.id = torrent.hash
            warped.name = torrent.name
            warped.status = torrent.state
            warped.downloadDir = torrent['save_path']
            warped.hashString = torrent.hash
            warped.totalSize = torrent['total_size'] // size:选择的文件大小
            warped.addedDate = torrent['added_on']
            warped.trackers = torrent.tracker
            warped.isPrivate = '' // torrent.isPrivate
            warped.magnetLink = torrent['magnet_uri']
            // more
            warped.trackerStats = '' // torrent.trackerStats
            warped.files = torrent.files ? torrent.files.map(o => { return { name: o.name, length: o.size, bytesCompleted: o.size*o.progress } } ) : []
            warped.rateDownload = torrent['dlspeed']
            warped.rateUpload = torrent['upspeed']
            warped.downloadedEver = torrent.downloaded
            warped.leftUntilDone = torrent['amount_left']
            warped.comment = '' // torrent.comment
            warped.errorString = '' // torrent.errorString
        }

        return warped
    }
}